package rabbit.dead;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import rabbit.util.RabbitMqUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * Created with IntelliJ IDEA.
 * ClassName: DeadConsumer
 * Package: rabbit.dead
 * Description:
 * User: fzykd
 *
 * @Author: LQH
 * Date: 2023-10-26
 * Time: 14:20
 */

public class DeadConsumer {
    //死信队列消费者1

    //普通交换机
    public static final String NORMAL_EXCHANGE = "normal_exchange";
    //死信队列交换机
    public static final String DEAD_EXCHANGE = "dead_exchange";
    //普通队列
    public static final String NORMAL_QUEUE = "normal_queue";
    //私信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws IOException, TimeoutException {
        //获取信道
        Channel chanel = RabbitMqUtils.getChanel();
        //声明交换机 和 队列
        chanel.exchangeDeclare(NORMAL_EXCHANGE, BuiltinExchangeType.DIRECT);
        chanel.exchangeDeclare(DEAD_EXCHANGE,BuiltinExchangeType.DIRECT);
        //队列  队列名称 是否需要持久话  不需要共享  是否自动删除  其他参数 这个其他参数 就是设置转发死信队列机制的
        Map<String,Object> arg = new HashMap<>();
        //过期时间 在生产者也可以设置
        arg.put("x-message-ttl",10000);
        //正常队列设置私信交换机是谁 key是固定值 val指定交换机
        arg.put("x-dead-letter-exchange",DEAD_EXCHANGE);
        //有了交换机 还有routingKey
        arg.put("x-dead-letter-routing-key","list");

        //正常队列长度现在 之前的过期时间队列 就要先删除 创建新的队列
        //arg.put("x-max-length",6);

        chanel.queueDeclare(NORMAL_QUEUE,false,false,false,arg);
        //普通队列 如果出现一下下个情况 将消息发送给死信队列
        //1 消息被拒绝 2 消息TTL过期 3 队列达到最大长度
        //所以普通队列 要设置一定的参数 将信息转发给死信队列
        chanel.queueDeclare(DEAD_QUEUE,false,false,false,null);
        //普通交换机 和 普通队列捆绑
        chanel.queueBind(NORMAL_QUEUE,NORMAL_EXCHANGE,"zhangsan");
        //死信交换机 和 死信队列捆绑
        chanel.queueBind(DEAD_QUEUE,DEAD_EXCHANGE,"list");
        System.out.println("等待接收消息: .....");

        //接收消息 参数 消费哪个队列 是否自动应答1,接收到消息的回调,取消消费的回调
        DeliverCallback deliverCallback = (consumerTag,message) ->{
            //在这个判断消息 拒绝策略
            if (message.equals("info5")){
                //成为死信
                System.out.println("Consumer01接收的消息是: " + new String(message.getBody()) + "拒绝接收的");
                //false 不塞回队列
                chanel.basicReject(message.getEnvelope().getDeliveryTag(),false);
            }else {
                System.out.println("Consumer01接收的消息是: " + new String(message.getBody()));
                //批量应答
                chanel.basicAck(message.getEnvelope().getDeliveryTag(),false);
            }
        };
        //开启手动应答
        chanel.basicConsume(NORMAL_QUEUE,false,deliverCallback,consumerTag -> {});

    }


}
